﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Transactions;
using System.Web.Http;
using System.Web.Security;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Data.SqlClient;
using GrayParrot.Configuration;
using GrayParrot.Web.Security.Configuration;
using GrayParrot.Core;

namespace GrayParrot.Web.Security
{
    public class AuthenticationControllerBase : ApiController
    {
        public AuthenticationControllerBase()
        {
            Initialize();
        }

        private void Initialize()
        {
            ConfigurationManagerHelper cfgMgr = new ConfigurationManagerHelper();
            string m_applicationName = cfgMgr.GetApplicationName();
            string cnName = cfgMgr.GetConnectionStringName();

            string m_conn = ConfigurationManager.ConnectionStrings[cnName].ConnectionString;
            GrayParrot.Web.Security.Pages.ApplicationName = m_applicationName;
            GrayParrot.Web.Security.Pages.ConnectionString = m_conn;

            GrayParrot.Web.Security.Controls.ApplicationName = m_applicationName;
            GrayParrot.Web.Security.Controls.ConnectionString = m_conn;
        }

        [HttpPost]
        public string LoadAssignableRoles(JObject data)
        {
            string retValue = null;

            dynamic json = data;
            string m_pageId = json.PageId;

            string[] m_roles = Roles.GetAllRoles();

            string[] m_pageRoles = GrayParrot.Web.Security.Pages.GetRolesForPage(m_pageId);

            if (m_pageRoles != null)
            {
                m_roles = m_roles.Except(m_pageRoles).ToArray();
            }

            retValue = JsonConvert.SerializeObject(m_roles);

            return retValue;
        }

        [HttpPost]
        public string LoadPageRoles(JObject data)
        {
            string retValue = null;

            dynamic json = data;
            string m_pageId = json.PageId;

            string[] m_roles = GrayParrot.Web.Security.Pages.GetRolesForPage(m_pageId);

            retValue = JsonConvert.SerializeObject(m_roles);

            return retValue;
        }

        /// <summary>
        /// Deletes all assigned roles.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public string DeleteAllAssignedRoles(JObject data)
        {
            string retValue = GrayParrot.Web.Result.ReturnError("Cancellazione ruoli assegnati non riuscito !");

            try
            {
                dynamic json = data;
                string m_pageId = json.PageId;

                string[] m_currentRoles = GrayParrot.Web.Security.Pages.GetRolesForPage(m_pageId);

                if (m_currentRoles != null)
                {
                    GrayParrot.Web.Security.Pages.RemovePageFromRoles(m_pageId, m_currentRoles);
                }

                retValue = GrayParrot.Web.Result.ReturnSuccess("Cancellazione ruoli assegnati riuscito !");
            }
            catch (Exception ex)
            {
                retValue = GrayParrot.Web.Result.ReturnError(string.Format("Cancellazione ruoli assegnati non riuscito !{0}", ex.Message));
            }

            return retValue;
        }

        /// <summary>
        /// Updates the assigned roles.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public string UpdateAssignedRoles(JObject data)
        {
            string retValue = GrayParrot.Web.Result.ReturnError("Aggiornamento non riuscito !");

            try
            {
                dynamic json = data;
                string[] m_pageIds = json.PageIds.ToObject<string[]>();
                string[] m_roles = json.Roles.ToObject<string[]>();

                using (TransactionScope scope = new TransactionScope())
                {
                    foreach (string pageId in m_pageIds)
                    {
                        string[] m_currentRoles = GrayParrot.Web.Security.Pages.GetRolesForPage(pageId);

                        if (m_currentRoles != null)
                        {
                            GrayParrot.Web.Security.Pages.RemovePageFromRoles(pageId, m_currentRoles);
                        }

                        GrayParrot.Web.Security.Pages.AddPageToRoles(pageId, m_roles);
                    }

                    scope.Complete();
                }

                retValue = GrayParrot.Web.Result.ReturnSuccess("Aggiornamento riuscito !");
            }
            catch (Exception ex)
            {
                retValue = GrayParrot.Web.Result.ReturnError(string.Format("Aggiornamento non riuscito !{0}", ex.Message));
            }

            return retValue;
        }

        [HttpPost]
        public string UpdatePagesInRoles(JObject data)
        {
            string retValue = GrayParrot.Web.Result.ReturnError("Aggiornamento non riuscito !");

            try
            {
                dynamic json = data;
                PageInRole[] m_pagesInRoles = json.data.ToObject<PageInRole[]>();

                using (TransactionScope scope = new TransactionScope())
                {
                    foreach (PageInRole item in m_pagesInRoles)
                    {
                        if (item.Checked)
                        {
                            bool m_pir = GrayParrot.Web.Security.Pages.IsPageInRole(item.PageName, item.RoleName);
                            if (!m_pir)
                            {
                                GrayParrot.Web.Security.Pages.AddPageToRole(item.PageName, item.RoleName);
                            }
                        }
                        else
                        {
                            bool m_pir = GrayParrot.Web.Security.Pages.IsPageInRole(item.PageName, item.RoleName);
                            if (m_pir)
                            {
                                GrayParrot.Web.Security.Pages.RemovePageFromRole(item.PageName, item.RoleName);
                            }
                        }
                    }

                    scope.Complete();
                }

                retValue = GrayParrot.Web.Result.ReturnSuccess("Aggiornamento riuscito !");
            }
            catch (Exception ex)
            {
                retValue = GrayParrot.Web.Result.ReturnError(string.Format("Aggiornamento non riuscito !{0}", ex.Message));
            }

            return retValue;
        }

        [HttpGet]
        public string LoadPagesInRoles()
        {
            string retValue = null;

            System.Data.DataTable m_pages = GrayParrot.Web.Security.Pages.GetPagesInRoles();

            retValue = JsonConvert.SerializeObject(m_pages);

            return retValue;
        }

        [HttpPost]
        public string GetRoleId(string roleName)
        {
            string retValue = string.Empty;

            SqlParameter p1 = new SqlParameter("@ApplicationName", System.Data.SqlDbType.NVarChar, 256);
            p1.Value = GrayParrot.Web.Security.Pages.ApplicationName;
            SqlParameter p2 = new SqlParameter("@pageName", System.Data.SqlDbType.NVarChar, 256);
            p2.Value = roleName;
            SqlParameter pRT = new SqlParameter("@ReturnValue", System.Data.SqlDbType.Int);
            pRT.Direction = System.Data.ParameterDirection.ReturnValue;

            SqlParameter[] m_params = new SqlParameter[2] { p1, pRT };

            using (SqlConnection conn = new SqlConnection(GrayParrot.Web.Security.Pages.ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("[dbo].[aspnet_Roles_GetRoleId]", conn))
                {
                    cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    cmd.CommandTimeout = 600; // seconds
                    cmd.Parameters.AddRange(m_params);

                    conn.Open();

                    Guid m_roleId = Guid.Empty;
                    SqlDataReader reader = null;
                    reader = cmd.ExecuteReader();

                    if (reader.HasRows)
                    {
                        while (reader.Read())
                        {
                            m_roleId = Guid.Parse(reader.GetString(0));
                        }
                    }

                    foreach (SqlParameter param in cmd.Parameters)
                    {
                        if (param.Direction == System.Data.ParameterDirection.ReturnValue && param.Value != null && param.Value is int)
                        {
                            switch ((int)param.Value)
                            {
                                case 0:
                                    break;
                                case 1:
                                    throw new Exception(string.Format("ApplicationName not found: {0}", GrayParrot.Web.Security.Pages.ApplicationName));
                                default:
                                    throw new Exception("Unknown failure");
                            }
                        }
                    }
                }
            }

            return retValue;
        }

        [HttpPost]
        public string GetPageId(string pageName)
        {
            string retValue = string.Empty;

            Guid m_id = GrayParrot.Web.Security.Pages.GetPageId(pageName);

            retValue = JsonConvert.SerializeObject(m_id);

            return retValue;
        }

        /*
         
         Assegno il Ruolo
         Cancello il Ruolo
         Elenco controlli in un ruolo
         
         Verifico che il controllo esista nella pagina
         Verifico che il controllo esista nei ruoli dell'utente
         
         */

        [HttpPost]
        public string LoadControlsInRoles(JObject data)
        {
            string retValue = null;

            dynamic json = data;
            string m_pageName = json.pagename.ToString();

            System.Data.DataTable m_pages = GrayParrot.Web.Security.Controls.GetControlsInRoles(m_pageName);

            retValue = JsonConvert.SerializeObject(m_pages);

            return retValue;
        }

        [HttpGet]
        public List<NameValue> LoadStandardPages()
        {
            List<NameValue> retValue = null;

            string[] m_pages = GrayParrot.Web.Security.Pages.GetAllPages();

            if (m_pages.Count() > 0)
            {
                retValue = new List<NameValue>();

                foreach (string s in m_pages)
                {
                    retValue.Add(new NameValue() { name = s, value = s });
                }
            }

            return retValue;
        }

        [HttpGet]
        public List<NameValue> LoadControlsActions()
        {
            List<NameValue> retValue = null;

            string[] m_pages = GrayParrot.Web.Security.Controls.GetAllControls();

            if (m_pages.Count() > 0)
            {
                retValue = new List<NameValue>();

                foreach (string s in m_pages)
                {
                    retValue.Add(new NameValue() { name = s, value = s });
                }
            }

            return retValue;
        }
    }
}